/*
 * CITS2230 Operating Systems - Programming Project
 * Author:           Guilherme R. Lampert
 * Student number:   21203005
 */

#ifndef __SCHEDULER_HPP__
#define __SCHEDULER_HPP__

#include <vector>
#include <algorithm>

#include "Common.hpp"
#include "Process.hpp"
#include "MemoryManager.hpp"

// Interface to a process scheduler.
// Will have an underlaying implementation with a policy
// like FCFS or Round Robin.
class Scheduler {

public:

	// Factory method to create a new scheduler, using the policy
	// specified by the program arguments.
	static Scheduler * Create(int argc, const char * argv[]);

	// Runs the simulation and output results.
	void RunSimulation();

	virtual ~Scheduler();

protected:

	Scheduler(int memDumpTimeStep,
			const std::string & procListFile,
			const std::string & outputFile);

	virtual void RunWithMemorySimulation() = 0;

	virtual void RunWithoutMemorySimulation() = 0;

	// Destination of the simulation output.
	std::ostream & Output();

	// If >= 0, will generate memory dumps in the output of the simulation.
	int memDumpTimeStep;

	// When this variable is equal to memDumpTimeStep and memDumpTimeStep >= 0
	// a memory dump is generated in the output.
	int stepsElapsedSinceLastMemDump;

	// Global simulation time step counter.
	int simulationClock;

	// For the memory/cache/swap simulation
	MemoryManager memoryManager;

	// Queue of processes/jobs (ordered by time of arrival)
	std::vector<Process> processQueue;

private:

	// Parses the file with the list of processes to simulate and fills
	// the 'processQueue' array in a least to greatest arrival time order.
	void ParseProcessListFile(const std::string & procListFile);

	// Parse data from a process description file.
	void ParseProcess(const std::string & procFile);

	// If this file is open, we direct output to it,
	// else it goes to std::cout.
	std::ofstream outFile;
};

#endif // __SCHEDULER_HPP__
